package com.cuanbobox.utils;

import android.os.Environment;

import com.cuanbobox.base.App;
import com.cuanbobox.constant.CbConstant;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;

/**
 * Http文件下载
 */
public class HttpFileDownload extends Thread {
    private String path;
    private String saveDir;
    private int contentLength;
    private int progress;
    private DownloadListener downloadListener;

    /**
     * @param path 要下载文件的Http地址
     * @param downloadListener 下载文件的回调函数
     */
    public HttpFileDownload(String path, DownloadListener downloadListener) {
        this.path = path;
        this.downloadListener = downloadListener;
        saveDir = App.getInstance().getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath() + "/apk/";
        FileUtil.deleteAllFile(new File(saveDir));
        new File(saveDir).mkdirs();
    }

    @Override
    public void run() {
        super.run();
        try {
            URL url;
            HttpURLConnection connection;
            //统一资源
            url = new URL(path);
            //打开链接
            connection = (HttpURLConnection) url.openConnection();
            //设置链接超时
            connection.setConnectTimeout(4000);
            //设置请求方法
            connection.setRequestMethod("GET");
            //设置请求的字符编码
            connection.setRequestProperty("Charset", "utf-8");
            //设置connection打开链接资源
            connection.connect();

            //得到链接地址中的file路径
            String urlFilePath = connection.getURL().getFile();
            //得到url地址总文件名 file的separatorChar参数表示文件分离符
            String fileName = urlFilePath.substring(urlFilePath.lastIndexOf(File.separatorChar) + 1);
            //创建一个文件对象用于存储下载的文件 此次的getFilesDir()方法只有在继承至Context类的类中
            // 可以直接调用其他类中必须通过Context对象才能调用，得到的是内部存储中此应用包名下的文件路径
            //如果使用外部存储的话需要添加文件读写权限，5.0以上的系统需要动态获取权限 此处不在不做过多说明。
            File file = new File(saveDir, fileName);
            //创建一个文件输出流
            FileOutputStream outputStream = new FileOutputStream(file);

            //得到链接的响应码 200为成功
            int responseCode = connection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                //得到服务器响应的输入流
                InputStream inputStream = connection.getInputStream();
                //获取请求的内容总长度
                contentLength = connection.getContentLength();
                LogUtil.add("文件总长度", "" + contentLength, "Http文件下载");
                if (downloadListener != null) {
                    downloadListener.start(contentLength);
                }
                //创建缓冲输入流对象，相对于inputStream效率要高一些
                BufferedInputStream bfi = new BufferedInputStream(inputStream);
                //此处的len表示每次循环读取的内容长度
                int len;
                //已经读取的总长度
                //bytes是用于存储每次读取出来的内容
                byte[] bytes = new byte[1024 * 10];
                long startTime = new Date().getTime();
                while ((len = bfi.read(bytes)) != -1) {
                    //每次读取完了都将len累加在totle里
                    progress += len;
                    LogUtil.add("下载进度", progress + "/" + contentLength, "Http文件下载");
                    //通过文件输出流写入从服务器中读取的数据
                    outputStream.write(bytes, 0, len);
                    if (downloadListener != null) {
                        downloadListener.progress(progress, contentLength);
                    }
                }
                long endTime = new Date().getTime();
                //关闭打开的流对象
                outputStream.close();
                inputStream.close();
                bfi.close();
                if (downloadListener != null) {
                    downloadListener.finish(file.getAbsolutePath());
                }
                LogUtil.add("下载完成", "耗时" + (endTime - startTime) + "毫秒", "Http文件下载");
                BroadcastUtil.sendBroadcast(CbConstant.TYPE_INSTALL_APK,file.getAbsolutePath());
            }
        } catch (Exception e) {
            e.printStackTrace();
            if (downloadListener != null) {
                downloadListener.error();
            }
        }
    }

    public interface DownloadListener {
        void start(int sumSize);

        void progress(int nowProgress, int sumSize);

        void finish(String savePath);

        void error();
    }
}
